package com.ruoyi.workflow.service.impl;

import java.io.InputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipInputStream;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.workflow.domain.BpmnInfo;
import com.ruoyi.workflow.service.IBpmnInfoService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.ProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.workflow.mapper.BpmnInfoMapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 流程定义Service业务层处理
 *
 * @author lhl
 * @date 2022-11-14
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BpmnInfoServiceImpl extends ServiceImpl<BpmnInfoMapper, BpmnInfo> implements IBpmnInfoService {
    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;
    @Autowired
    private ISysDictTypeService typeService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessDiagramGenerator processDiagramGenerator;

    /**
     * 查询流程定义列表
     *
     * @param bpmnInfo 流程定义
     * @return 流程定义
     */
    @Override
    public List<BpmnInfo> selectBpmnInfoList(BpmnInfo bpmnInfo) {
        return bpmnInfoMapper.selectBpmnInfoList(bpmnInfo);
    }


    /**
     * 批量删除流程定义
     *
     * @param ids 需要删除的流程定义主键
     * @return 结果
     */

    public boolean deleteBpmnInfoByIds(Long[] ids) {

        for (Long id : ids) {
            BpmnInfo bpmnInfo = super.getById(id);
            if (bpmnInfo == null) {
                throw new ServiceException("参数错误, 流程信息不存在");
            }
            try {
                repositoryService.deleteDeployment(bpmnInfo.getDeploymentId());
            } catch (Exception e) {
                throw new ServiceException("删除失败, 当前存在正在进行的审核流程");
            }
        }
        return super.removeBatchByIds(Arrays.asList(ids));
    }

    @Override
    public void deploy(InputStream bpmnFileInputStream, BpmnInfo bpmnInfo) {
        //1.保存bpmnLabel:流程定义名称
        //获取文件流程定义类型对应的字典类型标签
        List<SysDictData> sys_audit_type = typeService.selectDictDataByType("sys_audit_type");
        for (SysDictData data : sys_audit_type
        ) {
            if (data.getDictValue().equals(bpmnInfo.getBpmnType())) {
                //将字典类型标签设置到bpmnInfo中的流程名称--保存bpmnlabel
                bpmnInfo.setBpmnLabel(data.getDictLabel());
            }
        }
        //部署流程定义
        Deployment deployment = null;
        if (FileUtils.getSuffix(bpmnInfo.getFileName()).equals("zip")) {
            deployment = repositoryService.createDeployment().addZipInputStream(new ZipInputStream(bpmnFileInputStream))
                    .name(bpmnInfo.getBpmnLabel()).deploy();
        } else {
            deployment = repositoryService.createDeployment().addInputStream(bpmnInfo.getFileName(), bpmnFileInputStream).name(bpmnInfo.getBpmnLabel()).deploy();
        }
        //保存部署信息
        //2.部署时间
        bpmnInfo.setDeploymentId(deployment.getId());
        bpmnInfo.setDeployTime(deployment.getDeploymentTime());
        //3.保存部署流程定义的key
        bpmnInfo.setProcessDefinitionKey(bpmnInfo.getBpmnType());
        //4.基于流程定义 key 查询流程定义对象,获取版本号
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(bpmnInfo.getBpmnType()).deploymentId(deployment.getId()).singleResult();
        bpmnInfo.setVersion((long) processDefinition.getVersion());
        if (processDefinition == null) {
            throw new ServiceException("流程定义key不正确");
        }
        //保存到数据库
        super.save(bpmnInfo);
    }


    @Override
    public BpmnInfo getById(Serializable id) {

        BpmnInfo byId = super.getById(id);
        if (byId == null) {
            throw new ServiceException("参数错误");

        }
        return byId;
    }

    @Override
    public InputStream getView(Long id, String type) {
        BpmnInfo bpmnInfo = super.getById(id);//基于id获取bpmninfo
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(bpmnInfo.getDeploymentId()).singleResult();
        if ("image".equals(type)) {
            //查看图片
            if (StringUtils.isNotEmpty(processDefinition.getDiagramResourceName())) {
                //数据库中有图片文件,查询出来并返回
                return repositoryService.getResourceAsStream(bpmnInfo.getDeploymentId(), processDefinition.getDiagramResourceName());
            } else {
                //如果没有调用图片生成器生成流程文件并返回
                //获取bpmnmodel对象
                BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
                return processDiagramGenerator.generateDiagram(bpmnModel, "宋体", "宋体", "宋体");
            }
        } else {
            //查看bpmn文件
            System.out.println(processDefinition.getResourceName());
            System.out.println(bpmnInfo.getFileName());
            return repositoryService.getResourceAsStream(bpmnInfo.getDeploymentId(), processDefinition.getResourceName());
        }

    }


}
